package org.cybzacg.encryption.enums;

/**
 * 国密算法枚举
 * 定义中国商用密码算法标准
 * 
 * @author encryption team
 * @version 1.0
 */
public enum NationalAlgorithm {
    
    /**
     * SM2椭圆曲线公钥密码算法
     * 用于数字签名、密钥交换和加密
     */
    SM2("SM2", "椭圆曲线公钥密码算法", 256),
    
    /**
     * SM3密码杂凑算法
     * 用于计算杂凑值和消息认证码
     */
    SM3("SM3", "密码杂凑算法", 256),
    
    /**
     * SM4分组密码算法
     * 用于数据的加密和解密
     */
    SM4("SM4", "分组密码算法", 128);
    
    private final String name;
    private final String description;
    private final int keySize;
    
    NationalAlgorithm(String name, String description, int keySize) {
        this.name = name;
        this.description = description;
        this.keySize = keySize;
    }
    
    /**
     * 获取算法名称
     * 
     * @return 算法名称
     */
    public String getName() {
        return name;
    }
    
    /**
     * 获取算法描述
     * 
     * @return 算法描述
     */
    public String getDescription() {
        return description;
    }
    
    /**
     * 获取密钥长度（位）
     * 
     * @return 密钥长度
     */
    public int getKeySize() {
        return keySize;
    }
    
    /**
     * 获取密钥长度（字节）
     * 
     * @return 密钥长度（字节）
     */
    public int getKeySizeBytes() {
        return keySize / 8;
    }
    
    /**
     * 检查是否为非对称算法
     * 
     * @return 是否为非对称算法
     */
    public boolean isAsymmetric() {
        return this == SM2;
    }
    
    /**
     * 检查是否为对称算法
     * 
     * @return 是否为对称算法
     */
    public boolean isSymmetric() {
        return this == SM4;
    }
    
    /**
     * 检查是否为哈希算法
     * 
     * @return 是否为哈希算法
     */
    public boolean isHash() {
        return this == SM3;
    }
    
    /**
     * 获取算法的标准名称
     * 
     * @return 标准名称
     */
    public String getStandardName() {
        switch (this) {
            case SM2:
                return "SM2";
            case SM3:
                return "SM3";
            case SM4:
                return "SM4";
            default:
                return name;
        }
    }
    
    /**
     * 获取JCE算法名称
     * 
     * @return JCE算法名称
     */
    public String getJCEName() {
        switch (this) {
            case SM2:
                return "SM2";
            case SM3:
                return "SM3";
            case SM4:
                return "SM4";
            default:
                return name;
        }
    }
    
    /**
     * 获取算法的OID（对象标识符）
     * 
     * @return OID字符串
     */
    public String getOID() {
        switch (this) {
            case SM2:
                return "1.2.156.10197.1.301"; // SM2 OID
            case SM3:
                return "1.2.156.10197.1.401"; // SM3 OID
            case SM4:
                return "1.2.156.10197.1.104"; // SM4 OID
            default:
                return null;
        }
    }
    
    /**
     * 获取算法的变换名称
     * 
     * @return 变换名称
     */
    public String getTransformation() {
        switch (this) {
            case SM2:
                return "SM2";
            case SM3:
                return "SM3";
            case SM4:
                return "SM4/CBC/PKCS7Padding";
            default:
                return name;
        }
    }
    
    /**
     * 获取算法的块大小（字节）
     * 
     * @return 块大小
     */
    public int getBlockSize() {
        switch (this) {
            case SM2:
                return 0; // 非块算法
            case SM3:
                return 64; // SM3输出512位=64字节
            case SM4:
                return 16; // SM4块大小128位=16字节
            default:
                return 0;
        }
    }
    
    /**
     * 获取算法的输出长度（字节）
     * 
     * @return 输出长度
     */
    public int getOutputLength() {
        switch (this) {
            case SM2:
                return 0; // 取决于操作类型
            case SM3:
                return 32; // SM3输出256位=32字节
            case SM4:
                return 0; // 取决于输入长度
            default:
                return 0;
        }
    }
    
    /**
     * 根据名称查找算法
     * 
     * @param name 算法名称
     * @return 算法枚举，如果未找到返回null
     */
    public static NationalAlgorithm fromName(String name) {
        if (name == null) {
            return null;
        }
        
        try {
            return NationalAlgorithm.valueOf(name.toUpperCase());
        } catch (IllegalArgumentException e) {
            return null;
        }
    }
    
    /**
     * 根据OID查找算法
     * 
     * @param oid 对象标识符
     * @return 算法枚举，如果未找到返回null
     */
    public static NationalAlgorithm fromOID(String oid) {
        if (oid == null) {
            return null;
        }
        
        for (NationalAlgorithm algorithm : values()) {
            if (oid.equals(algorithm.getOID())) {
                return algorithm;
            }
        }
        return null;
    }
    
    /**
     * 获取所有非对称算法
     * 
     * @return 非对称算法数组
     */
    public static NationalAlgorithm[] getAsymmetricAlgorithms() {
        return new NationalAlgorithm[]{SM2};
    }
    
    /**
     * 获取所有对称算法
     * 
     * @return 对称算法数组
     */
    public static NationalAlgorithm[] getSymmetricAlgorithms() {
        return new NationalAlgorithm[]{SM4};
    }
    
    /**
     * 获取所有哈希算法
     * 
     * @return 哈希算法数组
     */
    public static NationalAlgorithm[] getHashAlgorithms() {
        return new NationalAlgorithm[]{SM3};
    }
    
    /**
     * 检查算法是否受支持
     * 
     * @param algorithm 算法
     * @return 是否受支持
     */
    public static boolean isSupported(NationalAlgorithm algorithm) {
        return algorithm != null && java.util.Arrays.asList(values()).contains(algorithm);
    }
    
    /**
     * 获取算法的安全级别
     * 
     * @return 安全级别（1-5，5为最高）
     */
    public int getSecurityLevel() {
        switch (this) {
            case SM2:
                return 5; // 椭圆曲线，高安全性
            case SM3:
                return 4; // 哈希算法，高安全性
            case SM4:
                return 3; // 分组密码，良好安全性
            default:
                return 1;
        }
    }
    
    /**
     * 获取算法的性能评级
     * 
     * @return 性能评级（1-5，5为最高）
     */
    public int getPerformanceRating() {
        switch (this) {
            case SM2:
                return 2; // 椭圆曲线，相对较慢
            case SM3:
                return 4; // 哈希算法，较快
            case SM4:
                return 5; // 分组密码，很快
            default:
                return 1;
        }
    }
    
    /**
     * 获取推荐的用途场景
     * 
     * @return 推荐用途
     */
    public String getRecommendedUsage() {
        switch (this) {
            case SM2:
                return "数字签名、密钥交换、数据加密";
            case SM3:
                return "消息认证、数据完整性校验、密码存储";
            case SM4:
                return "敏感数据加密、通信加密、数据存储";
            default:
                return "通用加密";
        }
    }
    
    @Override
    public String toString() {
        return String.format("%s (%s) - %d位 - %s", 
            name, description, keySize, getRecommendedUsage());
    }
}
